package com.xinqi.common.web.current;

import com.xinqi.common.base.current.Current;
import com.xinqi.common.base.current.Currents;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.annotation.ValueConstants;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver;

import javax.servlet.ServletException;
import java.util.Objects;

/**
 * @author linkai
 * @since 2017/4/20
 */
public class CurrentMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(Current.class);
    }

    @Override
    protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
        Current ann = parameter.getParameterAnnotation(Current.class);
        return new NamedValueInfo(parameter.getParameterType().getCanonicalName(), ann.required(),
            ValueConstants.DEFAULT_NONE);
    }

    @Override
    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) {
        return Currents.resolve(parameter.nestedIfOptional().getParameterType()).orElse(null);
    }

    @Override
    protected void handleMissingValue(String name, MethodParameter parameter) throws ServletException {
        throw new IllegalArgumentException(
            String.format("Required current %s not found for %s.%s", parameter.getParameterType().getSimpleName(),
                Objects.requireNonNull(parameter.getMethod()).getDeclaringClass().getSimpleName(),
                parameter.getMethod().getName()));
    }

}
